﻿using Microsoft.Office.Interop.Word;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;

// 参考代码： https://www.cnblogs.com/zhenzaizai/p/7782748.html

namespace ConsoleApp1
{
    public class WordService : IDisposable
    {
        private Application _wordApp = null;
        private Document _nowDocument = null;
        private Document _oldDocument = null;

        public WordService(){
            GetNewWordApplication();
        }

        private void GetNewWordApplication() {
            _wordApp = new Application();
        }

        public void Open(string tempDoc)
        {
            object objTempDoc = tempDoc;
            object objMissing = Missing.Value;

            _nowDocument = _wordApp.Documents.Open(
               ref objTempDoc, //FileName 
               ref objMissing, //ConfirmVersions 
               ref objMissing, //ReadOnly 
               ref objMissing, //AddToRecentFiles 
               ref objMissing, //PasswordDocument 
               ref objMissing, //PasswordTemplate 
               ref objMissing, //Revert 
               ref objMissing, //WritePasswordDocument 
               ref objMissing, //WritePasswordTemplate 
               ref objMissing, //Format 
               ref objMissing, //Enconding 
               ref objMissing, //Visible 
               ref objMissing, //OpenAndRepair 
               ref objMissing, //DocumentDirection 
               ref objMissing, //NoEncodingDialog 
               ref objMissing //XMLTransform 
               );
            _nowDocument.Activate();
        }

        public void SaveAs(string outDoc)
        {
            object objMissing = Missing.Value;
            object objOutDoc = outDoc;
            _nowDocument.SaveAs(
            ref objOutDoc, //FileName 
            ref objMissing, //FileFormat 
            ref objMissing, //LockComments 
            ref objMissing, //PassWord 
            ref objMissing, //AddToRecentFiles 
            ref objMissing, //WritePassword 
            ref objMissing, //ReadOnlyRecommended 
            ref objMissing, //EmbedTrueTypeFonts 
            ref objMissing, //SaveNativePictureFormat 
            ref objMissing, //SaveFormsData 
            ref objMissing, //SaveAsAOCELetter, 
            ref objMissing, //Encoding 
            ref objMissing, //InsertLineBreaks 
            ref objMissing, //AllowSubstitutions 
            ref objMissing, //LineEnding 
            ref objMissing //AddBiDiMarks 
            );
        }


        #region 循环合并多个文件（复制合并重复的文件）
        /// <summary> 
        /// 循环合并多个文件（复制合并重复的文件） 
        /// </summary> 
        /// <param name="tempDoc">模板文件</param> 
        /// <param name="arrCopies">需要合并的文件</param> 
        /// <param name="outDoc">合并后的输出文件</param> 
        public void CopyMerge(string tempDoc, string[] arrCopies, string outDoc)
        {
            object objMissing = Missing.Value;
            object objFalse = false;
            object objTarget = WdMergeTarget.wdMergeTargetSelected;
            object objUseFormatFrom = WdUseFormattingFrom.wdFormattingFromSelected;
            try
            {
                //打开模板文件 
                Open(tempDoc);
                foreach (string strCopy in arrCopies)
                {
                    _nowDocument.Merge(
                    strCopy, //FileName 
                    ref objTarget, //MergeTarget 
                    ref objMissing, //DetectFormatChanges 
                    ref objUseFormatFrom, //UseFormattingFrom 
                    ref objMissing //AddToRecentFiles 
                    );
                    _oldDocument = _nowDocument;
                    _nowDocument = _wordApp.ActiveDocument;
                    if (_oldDocument != null)
                    {
                        _oldDocument.Close(
                        ref objFalse, //SaveChanges 
                        ref objMissing, //OriginalFormat 
                        ref objMissing //RouteDocument 
                        );
                    }
                }
                //保存到输出文件 
                SaveAs(outDoc);
                foreach (Document objDocument in _wordApp.Documents)
                {
                    objDocument.Close(
                    ref objFalse, //SaveChanges 
                    ref objMissing, //OriginalFormat 
                    ref objMissing //RouteDocument 
                    );
                }
            }
            finally
            {
                _wordApp.Quit(
                ref objMissing, //SaveChanges 
                ref objMissing, //OriginalFormat 
                ref objMissing //RoutDocument 
                );
                GetNewWordApplication();
            }
        }
        /// <summary> 
        /// 循环合并多个文件（复制合并重复的文件） 
        /// </summary> 
        /// <param name="tempDoc">模板文件</param> 
        /// <param name="arrCopies">需要合并的文件</param> 
        /// <param name="outDoc">合并后的输出文件</param> 
        public void CopyMerge(string tempDoc, string strCopyFolder, string outDoc)
        {
            string[] arrFiles = Directory.GetFiles(strCopyFolder);
            CopyMerge(tempDoc, arrFiles, outDoc);
        }
        #endregion

        /// <summary>
        /// 创建一个空模板文件
        /// </summary>
        /// <param name="path"></param>
        /// <param name="outDoc"></param>
        public void CreateEmptyTempDoc(string path, string outDoc)
        {
            object objMissing = Missing.Value;
            object objFalse = false;
            //object confirmConversion = false;
            //object link = false;
            //object attachment = false;
            //object Nothing = Missing.Value;
            //object unite = Microsoft.Office.Interop.Word.WdUnits.wdStory;
            //object unite2 = Microsoft.Office.Interop.Word.WdUnits.wdTable;
 
            try
            {
                //打开模板文件 
                Open(path);

                foreach (Document item in _wordApp.Documents)
                {
                    foreach (Paragraph item2 in item.Paragraphs)
                    {
                        item2.Range.Delete();
                    }

                    foreach (Table item2 in item.Tables)
                    {
                        item.Range().Delete();
                    }
                }

                //objApp.Selection.Delete(ref unite2, ref Nothing);
                //保存到输出文件 
                SaveAs(outDoc);
                foreach (Document objDocument in _wordApp.Documents)
                {

                    objDocument.Close(
                    ref objFalse, //SaveChanges 
                    ref objMissing, //OriginalFormat 
                    ref objMissing //RouteDocument 
                    );
                }
            }
            finally
            {
                _wordApp.Quit(
                ref objMissing, //SaveChanges 
                ref objMissing, //OriginalFormat 
                ref objMissing //RoutDocument 
                );
                GetNewWordApplication();
            }
        }

        #region 循环合并多个文件（插入合并文件）
        /// <summary> 
        /// 循环合并多个文件（插入合并文件） 
        /// </summary> 
        /// <param name="tempDoc">模板文件</param> 
        /// <param name="arrCopies">需要合并的文件</param> 
        /// <param name="outDoc">合并后的输出文件</param> 
        public void InsertMerge(string tempDoc, List<string> arrCopies, string outDoc)
        {
            object objMissing = Missing.Value;
            object objFalse = false;
            object confirmConversion = false;
            object link = false;
            object attachment = false;
            try
            {
                //打开模板文件 
                Open(tempDoc);
                foreach (string strCopy in arrCopies)
                {
                    _wordApp.Selection.InsertFile(
                    strCopy,
                    ref objMissing,
                    ref confirmConversion,
                    ref link,
                    ref attachment
                    );
                    //objApp.Selection.Delete();
                }
                //保存到输出文件 
                SaveAs(outDoc);
                foreach (Document objDocument in _wordApp.Documents)
                {
                    objDocument.Close(
                    ref objFalse, //SaveChanges 
                    ref objMissing, //OriginalFormat 
                    ref objMissing //RouteDocument 
                    );
                }
            }
            finally
            {
                _wordApp.Quit(
                ref objMissing, //SaveChanges 
                ref objMissing, //OriginalFormat 
                ref objMissing //RoutDocument 
                );
                GetNewWordApplication();
            }
        }
        /// <summary> 
        /// 循环合并多个文件（插入合并文件） 
        /// </summary> 
        /// <param name="tempDoc">模板文件</param> 
        /// <param name="arrCopies">需要合并的文件</param> 
        /// <param name="outDoc">合并后的输出文件</param> 
        public void InsertMerge(string tempDoc, string strCopyFolder, string outDoc)
        {
            string[] arrFiles = Directory.GetFiles(strCopyFolder);
            var files = new List<string>();
            for (int i = 0; i < arrFiles.Count(); i++)
            {
                if (arrFiles[i].Contains("doc"))
                {
                    files.Add(arrFiles[i]);
                }
            }
            InsertMerge(tempDoc, files, outDoc);
        }
        #endregion

        #region 合并文件夹下的所有txt文件

        /// <summary>
        /// 合并多个txt文件
        /// </summary>
        /// <param name="infileName">文件存在的路劲</param>
        /// <param name="outfileName">输出文件名称</param>
        public void CombineFile(string filePath, string outfileName)
        {
            string[] infileName = Directory.GetFiles(filePath, "*.txt");
            int b;
            int n = infileName.Length;
            FileStream[] fileIn = new FileStream[n];
            using (FileStream fileOut = new FileStream(outfileName, FileMode.Create))
            {
                for (int i = 0; i < n; i++)
                {
                    try
                    {
                        fileIn[i] = new FileStream(infileName[i], FileMode.Open);
                        while ((b = fileIn[i].ReadByte()) != -1)
                            fileOut.WriteByte((byte)b);
                    }
                    catch (System.Exception ex)
                    {
                        throw ex; //Console.WriteLine(ex.Message);
                    }
                    finally
                    {
                        fileIn[i].Close();
                    }
                }
            }
        }

        #endregion

        #region IDisposable Support
        private bool disposed = false; // 要检测冗余调用

        protected virtual void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    // TODO: 释放托管状态(托管对象)。
                }

                // TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。
                // TODO: 将大型字段设置为 null。
                _wordApp = null;

                disposed = true;
            }
        }

        // TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。
        //~WordClass()
        //{
        //    请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
        //    Dispose(false);
        //}

        // 添加此代码以正确实现可处置模式。
        public void Dispose()
        {
            // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
            Dispose(true);
            // TODO: 如果在以上内容中替代了终结器，则取消注释以下行。
            // GC.SuppressFinalize(this);
        }
        #endregion
    }
}
